#STATEFUL
from django.http import HttpResponse
from django.shortcuts import render_to_response as show_dialog
from django import forms
from itertools import count
from datetime import datetime
import random

states = {}

def counter(request):
    gen = states.setdefault('counter', count())
    return HttpResponse(str(gen.next()))

class StatefulView(object):
    STATES = {}
    @classmethod
    def handle(cls, request, *a, **kw):
        keyname = cls.__name__+'_'+request.session.session_key
        if keyname in cls.STATES:
            gen = cls.STATES[keyname]
            response = gen.send((request, a, kw))
        else:
            gen = cls().main()
            cls.STATES[keyname] = gen
            response = gen.next()
            
        if isinstance(response, tuple):
            if response[1]:
                del cls.STATES[keyname]
            response = response[0]
        
        return response
    
    def main(self, request, *a, **kw):
        raise NotImplementedError("%s must implement 'main'" % self.__class__.__name__)
    
class Game(StatefulView):    
    def main(self):
        yield show_dialog('welcome.html')

        score = {'computer':0, 'human': 0, 'tie': 0}
        round = 0
        while (score['computer'] + score['human']) < 3:
            round += 1
            computer = self.get_computer_choice()
            human = None
            form = self.ChoiceForm()
            while not human:
                input, a, kw = yield show_dialog('ask_player_choice.html', {'form': form, 'round': round})
                form = self.ChoiceForm(input.GET)
                if form.is_valid():
                    human = form.cleaned_data['choice']
            
            score[self.match_result(human, computer)] += 1
        
        response = show_dialog('score.html', {
            'score': score,
            'rounds': round,
            'human_won': score['computer'] < score['human'],})
        
        yield response, True

    class ChoiceForm(forms.Form):
        choices = [(x,x) for x in ('piedra', 'papel','tijera')]
        choice = forms.ChoiceField(choices=choices, widget=forms.RadioSelect)
        
    def get_computer_choice(self):
        return random.choice(self.ChoiceForm.choices)[0]
    
    @classmethod
    def match_result(cls, human, computer):
        matches = {'piedra': 'tijera',
                   'papel': 'piedra',
                   'tijera': 'papel',}
        
        if computer == human: return 'tie'
        elif matches[computer] == human: return 'computer'
        else: return 'human'
